xen: Split domain_flags into discrete first-class fields in the
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 29 Mar 2007 14:14:26 +0000 (15:14 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 29 Mar 2007 14:14:26 +0000 (15:14 +0100)
domain structure. This makes them quicker to access, and simplifies
domain pause and checking of runnable status.
Signed-off-by: Keir Fraser <keir@xensource.com>
20 files changed:
xen/arch/ia64/xen/mm.c
xen/arch/powerpc/mm.c
xen/arch/x86/domain.c
xen/arch/x86/domain_build.c
xen/arch/x86/mm.c
xen/arch/x86/mm/hap/hap.c
xen/arch/x86/mm/shadow/common.c
xen/arch/x86/mm/shadow/multi.c
xen/arch/x86/x86_64/asm-offsets.c
xen/arch/x86/x86_64/entry.S
xen/common/domain.c
xen/common/domctl.c
xen/common/event_channel.c
xen/common/grant_table.c
xen/common/keyhandler.c
xen/common/memory.c
xen/common/page_alloc.c
xen/common/schedule.c
xen/include/xen/sched.h
xen/include/xen/spinlock.h

index e055757cc2632e56aae4c0d313a330325f50e0af..6cd28d34578ab44c5396f4e699d61ececb39e759 100644 (file)
@@ -400,7 +400,7 @@ share_xen_page_with_guest(struct page_info *page,
     ASSERT(page->count_info == 0);
 
     /* Only add to the allocation list if the domain isn't dying. */
-    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
+    if ( !d->is_dying )
     {
         page->count_info |= PGC_allocated | 1;
         if ( unlikely(d->xenheap_pages++ == 0) )
@@ -1935,8 +1935,7 @@ void put_page_type(struct page_info *page)
          * page-table pages if we detect a referential loop.
          * See domain.c:relinquish_list().
          */
-        ASSERT((x & PGT_validated) ||
-               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
+        ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
 
         if ( unlikely((nx & PGT_count_mask) == 0) )
         {
index d48ce3a7f51e8f60b42ccd487f587d444cd64c76..2dec97ad1b9fed4aaaed9f2ad6b2d2ea0d643f96 100644 (file)
@@ -106,7 +106,7 @@ void share_xen_page_with_guest(
     ASSERT(page->count_info == 0);
 
     /* Only add to the allocation list if the domain isn't dying. */
-    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
+    if ( !d->is_dying )
     {
         page->count_info |= PGC_allocated | 1;
         if ( unlikely(d->xenheap_pages++ == 0) )
@@ -218,8 +218,7 @@ void put_page_type(struct page_info *page)
          * page-table pages if we detect a referential loop.
          * See domain.c:relinquish_list().
          */
-        ASSERT((x & PGT_validated) || 
-               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
+        ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
 
         if ( unlikely((nx & PGT_count_mask) == 0) )
         {
@@ -402,7 +401,7 @@ int allocate_rma(struct domain *d, unsigned int order)
 void free_rma_check(struct page_info *page)
 {
     if (test_bit(_PGC_page_RMA, &page->count_info)) {
-        if (!test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags)) {
+        if (!page_get_owner(page)->is_dying) {
             panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
         } else {
             clear_bit(_PGC_page_RMA, &page->count_info);
@@ -439,8 +438,7 @@ ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
             mfn = d->arch.p2m[pfn];
         }
 #ifdef DEBUG
-        if (t != PFN_TYPE_NONE &&
-            (d->domain_flags & DOMF_dying) &&
+        if (t != PFN_TYPE_NONE && d->is_dying &&
             page_get_owner(mfn_to_page(mfn)) != d) {
             printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
                    __func__, t,
index 6a543a3a1b1fd2cd2a46d55be5713d294b6aeb7a..005813306c1a3e4e8a523f340868d7aac7c3bd1c 100644 (file)
@@ -274,7 +274,7 @@ int switch_native(struct domain *d)
     if ( !IS_COMPAT(d) )
         return 0;
 
-    clear_bit(_DOMF_compat, &d->domain_flags);
+    d->is_compat = 0;
     release_arg_xlat_area(d);
 
     /* switch gdt */
@@ -306,7 +306,7 @@ int switch_compat(struct domain *d)
     if ( IS_COMPAT(d) )
         return 0;
 
-    set_bit(_DOMF_compat, &d->domain_flags);
+    d->is_compat = 1;
 
     /* switch gdt */
     gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
index 96215da601a3d8333e6ed9f1f5301b52f68a17bd..a05060ee5e58ef6d35b28a7b995c5b275bd7300d 100644 (file)
@@ -324,7 +324,7 @@ int construct_dom0(struct domain *d,
     {
         l1_pgentry_t gdt_l1e;
 
-        set_bit(_DOMF_compat, &d->domain_flags);
+        d->is_compat = 1;
         v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];
 
         if ( nr_pages != (unsigned int)nr_pages )
index 5bd5ef720f610febb1ea9848f48110d90c0866ca..d6ca78726ae3d235d64552869d68df38ddfa923f 100644 (file)
@@ -271,7 +271,7 @@ void share_xen_page_with_guest(
     ASSERT(page->count_info == 0);
 
     /* Only add to the allocation list if the domain isn't dying. */
-    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
+    if ( !d->is_dying )
     {
         page->count_info |= PGC_allocated | 1;
         if ( unlikely(d->xenheap_pages++ == 0) )
@@ -806,8 +806,7 @@ void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d)
      * (Note that the undestroyable active grants are not a security hole in
      * Xen. All active grants can safely be cleaned up when the domain dies.)
      */
-    if ( (l1e_get_flags(l1e) & _PAGE_GNTTAB) &&
-         !(d->domain_flags & (DOMF_shutdown|DOMF_dying)) )
+    if ( (l1e_get_flags(l1e) & _PAGE_GNTTAB) && !d->is_shutdown && !d->is_dying )
     {
         MEM_LOG("Attempt to implicitly unmap a granted PTE %" PRIpte,
                 l1e_get_intpte(l1e));
@@ -2054,9 +2053,12 @@ int do_mmuext_op(
             /* A page is dirtied when its pin status is set. */
             mark_dirty(d, mfn);
            
-            /* We can race domain destruction (domain_relinquish_resources). */
+            /*
+             * We can race domain destruction (domain_relinquish_resources).
+             * NB. The dying-flag test must happen /after/ setting PGT_pinned.
+             */
             if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) &&
-                 test_bit(_DOMF_dying, &FOREIGNDOM->domain_flags) &&
+                 this_cpu(percpu_mm_info).foreign->is_dying &&
                  test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
                 put_page_and_type(page);
 
index f879c083c0b911684035ec64368673bb2a0547b7..47139f2627cff04b76723ab3a033634d9ab4e57f 100644 (file)
@@ -451,7 +451,7 @@ void hap_teardown(struct domain *d)
     mfn_t mfn;
     HERE_I_AM;
 
-    ASSERT(test_bit(_DOMF_dying, &d->domain_flags));
+    ASSERT(d->is_dying);
     ASSERT(d != current->domain);
 
     if ( !hap_locked_by_me(d) )
index ad4559aa2474d2910c5935e00be1ba6410eac719..8ef8b55b025b1be5b1b6d7292f726531960835ed 100644 (file)
@@ -2461,7 +2461,7 @@ void shadow_teardown(struct domain *d)
     struct list_head *entry, *n;
     struct page_info *pg;
 
-    ASSERT(test_bit(_DOMF_dying, &d->domain_flags));
+    ASSERT(d->is_dying);
     ASSERT(d != current->domain);
 
     if ( !shadow_locked_by_me(d) )
@@ -2992,7 +2992,7 @@ int shadow_domctl(struct domain *d,
         return -EINVAL;
     }
 
-    if ( unlikely(test_bit(_DOMF_dying, &d->domain_flags)) )
+    if ( unlikely(d->is_dying) )
     {
         gdprintk(XENLOG_INFO, "Ignoring shadow op on dying domain %u\n",
                  d->domain_id);
index 774d7408f826fe783c7ba3ea8b72004351d20fc4..7945913429785428658ddf4088f3752598e79184 100644 (file)
@@ -2821,9 +2821,9 @@ static int sh_page_fault(struct vcpu *v,
     {
         /* Couldn't get the sl1e!  Since we know the guest entries
          * are OK, this can only have been caused by a failed
-         * shadow_set_l*e(), which will have crashed the guest.  
+         * shadow_set_l*e(), which will have crashed the guest.
          * Get out of the fault handler immediately. */
-        ASSERT(test_bit(_DOMF_dying, &d->domain_flags));
+        ASSERT(d->is_shutdown);
         unmap_walk(v, &gw); 
         shadow_unlock(d);
         return 0;
index 053aee310eb110c3a8edffa2093f6072e60e3d5e..4e4b1036558894b0f3c773434605be8ff0926db3 100644 (file)
@@ -92,8 +92,7 @@ void __dummy__(void)
     OFFSET(VCPU_vmx_cr2, struct vcpu, arch.hvm_vmx.cpu_cr2);
     BLANK();
 
-    OFFSET(DOMAIN_domain_flags, struct domain, domain_flags);
-    DEFINE(_DOMF_compat, _DOMF_compat);
+    OFFSET(DOMAIN_is_compat, struct domain, is_compat);
     BLANK();
 
     OFFSET(VMCB_rax, struct vmcb_struct, rax);
index f89c89109c6e27302b7c61c49be5d6123733f71d..a69ac53de2d76a20effead5a5757961ac8875aed 100644 (file)
@@ -234,8 +234,8 @@ ENTRY(int80_direct_trap)
         jz    int80_slow_path
 
         movq  VCPU_domain(%rbx),%rax
-        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
-        j   compat_int80_direct_trap
+        testb $1,DOMAIN_is_compat(%rax)
+        jnz   compat_int80_direct_trap
 
         call  create_bounce_frame
         jmp   restore_all_guest
@@ -353,16 +353,12 @@ ENTRY(domain_crash_synchronous)
         GET_GUEST_REGS(%rax)
         movq  %rax,%rsp
         # create_bounce_frame() temporarily clobbers CS.RPL. Fix up.
-#ifdef CONFIG_COMPAT
         movq  CPUINFO_current_vcpu(%rax),%rax
         movq  VCPU_domain(%rax),%rax
-        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
-        setnc %al
+        testb $1,DOMAIN_is_compat(%rax)
+        set %al
         leal  (%rax,%rax,2),%eax
         orb   %al,UREGS_cs(%rsp)
-#else
-        orb   $3,UREGS_cs(%rsp)
-#endif
         # printk(domain_crash_synchronous_string)
         leaq  domain_crash_synchronous_string(%rip),%rdi
         xorl  %eax,%eax
@@ -375,14 +371,10 @@ ENTRY(ret_from_intr)
         GET_CURRENT(%rbx)
         testb $3,UREGS_cs(%rsp)
         jz    restore_all_xen
-#ifndef CONFIG_COMPAT
-        jmp   test_all_events
-#else
         movq  VCPU_domain(%rbx),%rax
-        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
-        jnc   test_all_events
+        testb $1,DOMAIN_is_compat(%rax)
+        j   test_all_events
         jmp   compat_test_all_events
-#endif
 
         ALIGN
 /* No special register assumptions. */
@@ -401,11 +393,9 @@ handle_exception_saved:
         testb $3,UREGS_cs(%rsp)
         jz    restore_all_xen
         leaq  VCPU_trap_bounce(%rbx),%rdx
-#ifdef CONFIG_COMPAT
         movq  VCPU_domain(%rbx),%rax
-        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
-        jc    compat_post_handle_exception
-#endif
+        testb $1,DOMAIN_is_compat(%rax)
+        jnz   compat_post_handle_exception
         testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
         jz    test_all_events
         call  create_bounce_frame
index 53ba781882b5786ee4465de91c2b066c1c19d8fd..f9e43a04ceda3eababb0171056fdb282dd2ba187 100644 (file)
@@ -59,7 +59,6 @@ struct domain *alloc_domain(domid_t domid)
     atomic_set(&d->refcnt, 1);
     spin_lock_init(&d->big_lock);
     spin_lock_init(&d->page_alloc_lock);
-    spin_lock_init(&d->pause_lock);
     INIT_LIST_HEAD(&d->page_list);
     INIT_LIST_HEAD(&d->xenpage_list);
 
@@ -161,9 +160,12 @@ struct domain *domain_create(domid_t domid, unsigned int domcr_flags)
 
     if ( !is_idle_domain(d) )
     {
-        set_bit(_DOMF_ctrl_pause, &d->domain_flags);
+        d->is_paused_by_controller = 1;
+        atomic_inc(&d->pause_count);
+
         if ( evtchn_init(d) != 0 )
             goto fail1;
+
         if ( grant_table_create(d) != 0 )
             goto fail2;
     }
@@ -262,9 +264,13 @@ void domain_kill(struct domain *d)
 {
     domain_pause(d);
 
-    if ( test_and_set_bit(_DOMF_dying, &d->domain_flags) )
+    /* Already dying? Then bail. */
+    if ( xchg(&d->is_dying, 1) )
         return;
 
+    /* Tear down state /after/ setting the dying flag. */
+    smp_wmb();
+
     gnttab_release_mappings(d);
     domain_relinquish_resources(d);
     put_domain(d);
@@ -278,7 +284,7 @@ void domain_kill(struct domain *d)
 
 void __domain_crash(struct domain *d)
 {
-    if ( test_bit(_DOMF_shutdown, &d->domain_flags) )
+    if ( d->is_shutdown )
     {
         /* Print nothing: the domain is already shutting down. */
     }
@@ -327,7 +333,7 @@ void domain_shutdown(struct domain *d, u8 reason)
     if ( d->domain_id == 0 )
         dom0_shutdown(reason);
 
-    if ( !test_and_set_bit(_DOMF_shutdown, &d->domain_flags) )
+    if ( !xchg(&d->is_shutdown, 1) )
         d->shutdown_code = reason;
 
     for_each_vcpu ( d, v )
@@ -341,7 +347,9 @@ void domain_pause_for_debugger(void)
     struct domain *d = current->domain;
     struct vcpu *v;
 
-    set_bit(_DOMF_ctrl_pause, &d->domain_flags);
+    atomic_inc(&d->pause_count);
+    if ( xchg(&d->is_paused_by_controller, 1) )
+        domain_unpause(d); /* race-free atomic_dec(&d->pause_count) */
 
     for_each_vcpu ( d, v )
         vcpu_sleep_nosync(v);
@@ -374,7 +382,7 @@ void domain_destroy(struct domain *d)
     struct domain **pd;
     atomic_t      old, new;
 
-    BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
+    BUG_ON(!d->is_dying);
 
     /* May be already destroyed, or get_domain() can race us. */
     _atomic_set(old, 0);
@@ -442,10 +450,7 @@ void domain_pause(struct domain *d)
 
     ASSERT(d != current->domain);
 
-    spin_lock(&d->pause_lock);
-    if ( d->pause_count++ == 0 )
-        set_bit(_DOMF_paused, &d->domain_flags);
-    spin_unlock(&d->pause_lock);
+    atomic_inc(&d->pause_count);
 
     for_each_vcpu( d, v )
         vcpu_sleep_sync(v);
@@ -454,43 +459,25 @@ void domain_pause(struct domain *d)
 void domain_unpause(struct domain *d)
 {
     struct vcpu *v;
-    int wake;
 
     ASSERT(d != current->domain);
 
-    spin_lock(&d->pause_lock);
-    wake = (--d->pause_count == 0);
-    if ( wake )
-        clear_bit(_DOMF_paused, &d->domain_flags);
-    spin_unlock(&d->pause_lock);
-
-    if ( wake )
+    if ( atomic_dec_and_test(&d->pause_count) )
         for_each_vcpu( d, v )
             vcpu_wake(v);
 }
 
 void domain_pause_by_systemcontroller(struct domain *d)
 {
-    struct vcpu *v;
-
-    BUG_ON(current->domain == d);
-
-    if ( !test_and_set_bit(_DOMF_ctrl_pause, &d->domain_flags) )
-    {
-        for_each_vcpu ( d, v )
-            vcpu_sleep_sync(v);
-    }
+    domain_pause(d);
+    if ( xchg(&d->is_paused_by_controller, 1) )
+        domain_unpause(d);
 }
 
 void domain_unpause_by_systemcontroller(struct domain *d)
 {
-    struct vcpu *v;
-
-    if ( test_and_clear_bit(_DOMF_ctrl_pause, &d->domain_flags) )
-    {
-        for_each_vcpu ( d, v )
-            vcpu_wake(v);
-    }
+    if ( xchg(&d->is_paused_by_controller, 0) )
+        domain_unpause(d);
 }
 
 int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt)
index 952c419f1ded20f21f8a64da1ecaf5e2707aef57..0f0c5998da6c104fe5c256b98ab3b1e117b0a8e3 100644 (file)
@@ -114,9 +114,9 @@ void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info)
     info->cpu_time = cpu_time;
 
     info->flags = flags |
-        ((d->domain_flags & DOMF_dying)      ? XEN_DOMINF_dying    : 0) |
-        ((d->domain_flags & DOMF_shutdown)   ? XEN_DOMINF_shutdown : 0) |
-        ((d->domain_flags & DOMF_ctrl_pause) ? XEN_DOMINF_paused   : 0) |
+        (d->is_dying                ? XEN_DOMINF_dying    : 0) |
+        (d->is_shutdown             ? XEN_DOMINF_shutdown : 0) |
+        (d->is_paused_by_controller ? XEN_DOMINF_paused   : 0) |
         d->shutdown_code << XEN_DOMINF_shutdownshift;
 
     if ( is_hvm_domain(d) )
@@ -288,7 +288,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
         if ( d != NULL )
         {
             ret = 0;
-            if ( test_and_clear_bit(_DOMF_shutdown, &d->domain_flags) )
+            if ( xchg(&d->is_shutdown, 0) )
                 for_each_vcpu ( d, v )
                     vcpu_wake(v);
             rcu_unlock_domain(d);
index 6054527286e75a8ab2d8b08dd696d3798f51dc13..783dfb99f1db7add88c1cc5df44af7c22fe12204 100644 (file)
@@ -529,8 +529,7 @@ void evtchn_set_pending(struct vcpu *v, int port)
     }
     
     /* Check if some VCPU might be polling for this event. */
-    if ( unlikely(test_bit(_DOMF_polling, &d->domain_flags)) &&
-         likely(test_and_clear_bit(_DOMF_polling, &d->domain_flags)) )
+    if ( unlikely(d->is_polling) && likely(xchg(&d->is_polling, 0)) )
     {
         for_each_vcpu ( d, v )
             if ( test_and_clear_bit(_VCPUF_polling, &v->vcpu_flags) )
index 2ea6ff37eb15189557fa846ed7f0fced6f8697fe..da6b743c3466b1002da23c77c93e311e5adbc4a3 100644 (file)
@@ -311,7 +311,7 @@ __gnttab_map_grant_ref(
                     get_page_and_type(mfn_to_page(frame), rd,
                                       PGT_writable_page))) )
     {
-        if ( !test_bit(_DOMF_dying, &rd->domain_flags) )
+        if ( !rd->is_dying )
             gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", frame);
         rc = GNTST_general_error;
         goto undo_out;
@@ -865,16 +865,16 @@ gnttab_transfer(
          * headroom.  Also, a domain mustn't have PGC_allocated
          * pages when it is dying.
          */
-        if ( unlikely(test_bit(_DOMF_dying, &e->domain_flags)) ||
+        if ( unlikely(e->is_dying) ||
              unlikely(e->tot_pages >= e->max_pages) ||
              unlikely(!gnttab_prepare_for_transfer(e, d, gop.ref)) )
         {
-            if ( !test_bit(_DOMF_dying, &e->domain_flags) )
+            if ( !e->is_dying )
                 gdprintk(XENLOG_INFO, "gnttab_transfer: "
                         "Transferee has no reservation "
                         "headroom (%d,%d) or provided a bad grant ref (%08x) "
-                        "or is dying (%lx)\n",
-                        e->tot_pages, e->max_pages, gop.ref, e->domain_flags);
+                        "or is dying (%d)\n",
+                        e->tot_pages, e->max_pages, gop.ref, e->is_dying);
             spin_unlock(&e->page_alloc_lock);
             rcu_unlock_domain(e);
             page->count_info &= ~(PGC_count_mask|PGC_allocated);
@@ -1094,7 +1094,7 @@ __gnttab_copy(
                  "source frame %lx invalid.\n", s_frame);
     if ( !get_page(mfn_to_page(s_frame), sd) )
     {
-        if ( !test_bit(_DOMF_dying, &sd->domain_flags) )
+        if ( !sd->is_dying )
             gdprintk(XENLOG_WARNING, "Could not get src frame %lx\n", s_frame);
         rc = GNTST_general_error;
         goto error_out;
@@ -1117,7 +1117,7 @@ __gnttab_copy(
                  "destination frame %lx invalid.\n", d_frame);
     if ( !get_page_and_type(mfn_to_page(d_frame), dd, PGT_writable_page) )
     {
-        if ( !test_bit(_DOMF_dying, &dd->domain_flags) )
+        if ( !dd->is_dying )
             gdprintk(XENLOG_WARNING, "Could not get dst frame %lx\n", d_frame);
         rc = GNTST_general_error;
         goto error_out;
@@ -1352,7 +1352,7 @@ gnttab_release_mappings(
     struct active_grant_entry *act;
     struct grant_entry   *sha;
 
-    BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
+    BUG_ON(!d->is_dying);
 
     for ( handle = 0; handle < gt->maptrack_limit; handle++ )
     {
index 471642aec6cd4be455a232aed9102dc242ec9a9e..e3eb0b9cee3d0a845445d9c08801573577bd6cec 100644 (file)
@@ -164,9 +164,9 @@ static void dump_domains(unsigned char key)
     {
         printk("General information for domain %u:\n", d->domain_id);
         cpuset_print(tmpstr, sizeof(tmpstr), d->domain_dirty_cpumask);
-        printk("    flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d "
+        printk("    refcnt=%d nr_pages=%d xenheap_pages=%d "
                "dirty_cpus=%s\n",
-               d->domain_flags, atomic_read(&d->refcnt),
+               atomic_read(&d->refcnt),
                d->tot_pages, d->xenheap_pages, tmpstr);
         printk("    handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
                "%02x%02x-%02x%02x%02x%02x%02x%02x vm_assist=%08lx\n",
index 26a2fde5eb98387b6697fb88621869d95a96b110..5adef9b07c3eb97ee5ae584ec2dff8fe0279b8ac 100644 (file)
@@ -345,7 +345,7 @@ static long memory_exchange(XEN_GUEST_HANDLE(xen_memory_exchange_t) arg)
 
     /*
      * Only support exchange on calling domain right now. Otherwise there are
-     * tricky corner cases to consider (e.g., DOMF_dying domain).
+     * tricky corner cases to consider (e.g., dying domain).
      */
     if ( unlikely(exch.in.domid != DOMID_SELF) )
     {
index 913c6c99869ec0f1e462eb7cf62cec39e6523dc1..b6e0afb1743d875471790f97d96d1a11ef291e85 100644 (file)
@@ -739,7 +739,7 @@ int assign_pages(
 
     spin_lock(&d->page_alloc_lock);
 
-    if ( unlikely(test_bit(_DOMF_dying, &d->domain_flags)) )
+    if ( unlikely(d->is_dying) )
     {
         gdprintk(XENLOG_INFO, "Cannot assign page to domain%d -- dying.\n",
                 d->domain_id);
@@ -869,7 +869,7 @@ void free_domheap_pages(struct page_info *pg, unsigned int order)
 
         spin_unlock_recursive(&d->page_alloc_lock);
 
-        if ( likely(!test_bit(_DOMF_dying, &d->domain_flags)) )
+        if ( likely(!d->is_dying) )
         {
             free_heap_pages(pfn_dom_zone_type(page_to_mfn(pg)), pg, order);
         }
index 560fadf504c26c3fc8ae23cfeace91f9e11ab747..6fc968126e64f71bf46994c0acb6d508747d8e1a 100644 (file)
@@ -313,7 +313,9 @@ static long do_poll(struct sched_poll *sched_poll)
     /* These operations must occur in order. */
     set_bit(_VCPUF_blocked, &v->vcpu_flags);
     set_bit(_VCPUF_polling, &v->vcpu_flags);
-    set_bit(_DOMF_polling, &d->domain_flags);
+    smp_wmb();
+    d->is_polling = 1;
+    smp_wmb();
 
     /* Check for events /after/ setting flags: avoids wakeup waiting race. */
     for ( i = 0; i < sched_poll->nr_ports; i++ )
index dc68f32eada2d7512969cc8aa44f21b0f9c774fc..2a86f778060974e8a26ac8ee5f437e8dbd8dcf78 100644 (file)
@@ -138,7 +138,6 @@ struct domain
     unsigned int     xenheap_pages;   /* # pages allocated from Xen heap    */
 
     /* Scheduling. */
-    int              shutdown_code; /* code value from OS (if DOMF_shutdown) */
     void            *sched_priv;    /* scheduler-specific data */
 
     struct domain   *next_in_list;
@@ -165,17 +164,26 @@ struct domain
     struct rangeset *iomem_caps;
     struct rangeset *irq_caps;
 
-    unsigned long    domain_flags;
-
     /* Is this an HVM guest? */
     bool_t           is_hvm;
     /* Is this guest fully privileged (aka dom0)? */
     bool_t           is_privileged;
     /* Is this guest being debugged by dom0? */
     bool_t           debugger_attached;
+    /* Is a 'compatibility mode' guest (semantics are arch specific)? */
+    bool_t           is_compat;
+    /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
+    bool_t           is_polling;
+    /* Is this guest dying (i.e., a zombie)? */
+    bool_t           is_dying;
+    /* Domain is paused by controller software? */
+    bool_t           is_paused_by_controller;
 
-    spinlock_t       pause_lock;
-    unsigned int     pause_count;
+    /* Guest has shut down (inc. reason code)? */
+    bool_t           is_shutdown;
+    int              shutdown_code;
+
+    atomic_t         pause_count;
 
     unsigned long    vm_assist;
 
@@ -452,28 +460,6 @@ extern struct domain *domain_list;
 #define _VCPUF_migrating       13
 #define VCPUF_migrating        (1UL<<_VCPUF_migrating)
 
-/*
- * Per-domain flags (domain_flags).
- */
- /* Guest shut itself down for some reason. */
-#define _DOMF_shutdown         0
-#define DOMF_shutdown          (1UL<<_DOMF_shutdown)
- /* Death rattle. */
-#define _DOMF_dying            1
-#define DOMF_dying             (1UL<<_DOMF_dying)
- /* Domain is paused by controller software. */
-#define _DOMF_ctrl_pause       2
-#define DOMF_ctrl_pause        (1UL<<_DOMF_ctrl_pause)
- /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
-#define _DOMF_polling          3
-#define DOMF_polling           (1UL<<_DOMF_polling)
- /* Domain is paused by the hypervisor? */
-#define _DOMF_paused           4
-#define DOMF_paused            (1UL<<_DOMF_paused)
- /* Domain is a compatibility one? */
-#define _DOMF_compat           5
-#define DOMF_compat            (1UL<<_DOMF_compat)
-
 static inline int vcpu_runnable(struct vcpu *v)
 {
     return ( !(v->vcpu_flags &
@@ -482,10 +468,7 @@ static inline int vcpu_runnable(struct vcpu *v)
                  VCPUF_paused |
                  VCPUF_blocked_in_xen |
                  VCPUF_migrating )) &&
-             !(v->domain->domain_flags &
-               ( DOMF_shutdown |
-                 DOMF_ctrl_pause |
-                 DOMF_paused )));
+             (atomic_read(&v->domain->pause_count) == 0) );
 }
 
 void vcpu_pause(struct vcpu *v);
@@ -511,8 +494,7 @@ static inline void vcpu_unblock(struct vcpu *v)
 #define IS_PRIV(_d) ((_d)->is_privileged)
 
 #ifdef CONFIG_COMPAT
-#define IS_COMPAT(_d)                                       \
-    (test_bit(_DOMF_compat, &(_d)->domain_flags))
+#define IS_COMPAT(_d) ((_d)->is_compat)
 #else
 #define IS_COMPAT(_d) 0
 #endif
index 11f83119d4e5869bd38d652f9b6989ee44acc1b6..fa8c82f8ea4b8044004ca3322a6cc736d378cf9b 100644 (file)
@@ -82,6 +82,13 @@ typedef struct { int gcc_is_buggy; } rwlock_t;
 #define write_lock(_lock)            _raw_write_lock(_lock)
 #define write_unlock(_lock)          _raw_write_unlock(_lock)
 
+/* Ensure a lock is quiescent between two critical operations. */
+static inline void spin_barrier(spinlock_t *lock)
+{
+    spin_lock(lock);
+    spin_unlock(lock);
+}
+
 #define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
 #define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED